package com.zhaopin.netty.guanwang;

import io.netty.buffer.ByteBuf;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;

/**
 * Handles a server-side channel.
 */
public class DiscardServerHandler extends ChannelInboundHandlerAdapter { // (1)

    /**
     * 1、DiscardServerHandler extends ChannelInboundHandlerAdapter，它是ChannelInboundHandler. ChannelInboundHandler提供了可以覆盖的各种事件处理程序方法。
     *    目前，扩展ChannelInboundHandlerAdapter而不是自己实现处理程序接口就足够了。
     * 2、我们在channelRead()这里覆盖事件处理程序方法。每当从客户端接收到新数据时，都会使用接收到的消息调用此方法。在这个例子中，接收到的消息的类型是ByteBuf。
     * 3、为了实现DISCARD协议，处理程序必须忽略接收到的消息。ByteBuf是一个引用计数对象，必须通过该release()方法显式释放。请记住，释放任何传递给处理程序的引用计数对象是处理程序的责任。通常，channelRead()处理程序方法的实现方式如下：
     * 4、该exceptionCaught()事件处理方法被调用，可抛出异常时被提出的Netty由于I/O错误或由处理器实现，由于在处理事件引发的异常。
     *    在大多数情况下，应该记录捕获的异常并在此处关闭EchoServerHandler其关联的通道，尽管此方法的实现可能会有所不同，具体取决于您要做什么来处理异常情况。例如，您可能希望在关闭连接之前发送带有错误代码的响应消息。
     * @param ctx
     * @param msg
     */



    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf in = (ByteBuf) msg;
        try {
            //1、这种低效循环实际上可以简化为： System.out.println(in.toString(io.netty.util.CharsetUtil.US_ASCII))
            //2、或者，你可以在in.release()这里做。
            while (in.isReadable()) { // (1)
                System.out.print((char) in.readByte());
                System.out.flush();
            }
        } finally {
            ReferenceCountUtil.release(msg); // (2)
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
        // Close the connection when an exception is raised.
        cause.printStackTrace();
        ctx.close();
    }
}